package com.bougaga.opensource.scheduler.core.scheduler;

import com.fasterxml.jackson.annotation.JsonInclude;

import java.io.Serializable;
import java.time.Duration;
import java.time.LocalDateTime;

/**
 * 调度器统计信息
 * 
 * @author bougaga
 * @since 1.0.0
 */
@JsonInclude(JsonInclude.Include.NON_NULL)
public class SchedulerStatistics implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    /**
     * 总任务数
     */
    private long totalTasks;
    
    /**
     * 待执行任务数
     */
    private long pendingTasks;
    
    /**
     * 执行中任务数
     */
    private long runningTasks;
    
    /**
     * 成功完成任务数
     */
    private long successTasks;
    
    /**
     * 失败任务数
     */
    private long failedTasks;
    
    /**
     * 取消任务数
     */
    private long cancelledTasks;
    
    /**
     * 重试任务数
     */
    private long retryTasks;
    
    /**
     * 超时任务数
     */
    private long timeoutTasks;
    
    /**
     * 平均执行时间（毫秒）
     */
    private double averageExecutionTime;
    
    /**
     * 最大执行时间（毫秒）
     */
    private long maxExecutionTime;
    
    /**
     * 最小执行时间（毫秒）
     */
    private long minExecutionTime;
    
    /**
     * 启动时间
     */
    private LocalDateTime startTime;
    
    /**
     * 运行时长（毫秒）
     */
    private long uptime;
    
    /**
     * 每秒处理任务数
     */
    private double tasksPerSecond;
    
    /**
     * 成功率
     */
    private double successRate;
    
    /**
     * 失败率
     */
    private double failureRate;
    
    public SchedulerStatistics() {
        this.startTime = LocalDateTime.now();
    }
    
    /**
     * 更新统计信息
     */
    public void update() {
        this.uptime = Duration.between(startTime, LocalDateTime.now()).toMillis();
        if (uptime > 0) {
            this.tasksPerSecond = (double) totalTasks / (uptime / 1000.0);
        }
        
        if (totalTasks > 0) {
            this.successRate = (double) successTasks / totalTasks * 100;
            this.failureRate = (double) failedTasks / totalTasks * 100;
        } else {
            // 当总任务数为0时，成功率和失败率都设为0
            this.successRate = 0.0;
            this.failureRate = 0.0;
        }
    }
    
    /**
     * 重置统计信息
     */
    public void reset() {
        this.totalTasks = 0;
        this.pendingTasks = 0;
        this.runningTasks = 0;
        this.successTasks = 0;
        this.failedTasks = 0;
        this.cancelledTasks = 0;
        this.retryTasks = 0;
        this.timeoutTasks = 0;
        this.averageExecutionTime = 0;
        this.maxExecutionTime = 0;
        this.minExecutionTime = 0;
        this.startTime = LocalDateTime.now();
        this.uptime = 0;
        this.tasksPerSecond = 0;
        this.successRate = 0;
        this.failureRate = 0;
    }
    
    // Getters and Setters
    public long getTotalTasks() {
        return totalTasks;
    }
    
    public void setTotalTasks(long totalTasks) {
        this.totalTasks = totalTasks;
    }
    
    public long getPendingTasks() {
        return pendingTasks;
    }
    
    public void setPendingTasks(long pendingTasks) {
        this.pendingTasks = pendingTasks;
    }
    
    public long getRunningTasks() {
        return runningTasks;
    }
    
    public void setRunningTasks(long runningTasks) {
        this.runningTasks = runningTasks;
    }
    
    public long getSuccessTasks() {
        return successTasks;
    }
    
    public void setSuccessTasks(long successTasks) {
        this.successTasks = successTasks;
    }
    
    public long getFailedTasks() {
        return failedTasks;
    }
    
    public void setFailedTasks(long failedTasks) {
        this.failedTasks = failedTasks;
    }
    
    public long getCancelledTasks() {
        return cancelledTasks;
    }
    
    public void setCancelledTasks(long cancelledTasks) {
        this.cancelledTasks = cancelledTasks;
    }
    
    public long getRetryTasks() {
        return retryTasks;
    }
    
    public void setRetryTasks(long retryTasks) {
        this.retryTasks = retryTasks;
    }
    
    public long getTimeoutTasks() {
        return timeoutTasks;
    }
    
    public void setTimeoutTasks(long timeoutTasks) {
        this.timeoutTasks = timeoutTasks;
    }
    
    public double getAverageExecutionTime() {
        return averageExecutionTime;
    }
    
    public void setAverageExecutionTime(double averageExecutionTime) {
        this.averageExecutionTime = averageExecutionTime;
    }
    
    public long getMaxExecutionTime() {
        return maxExecutionTime;
    }
    
    public void setMaxExecutionTime(long maxExecutionTime) {
        this.maxExecutionTime = maxExecutionTime;
    }
    
    public long getMinExecutionTime() {
        return minExecutionTime;
    }
    
    public void setMinExecutionTime(long minExecutionTime) {
        this.minExecutionTime = minExecutionTime;
    }
    
    public LocalDateTime getStartTime() {
        return startTime;
    }
    
    public void setStartTime(LocalDateTime startTime) {
        this.startTime = startTime;
    }
    
    public long getUptime() {
        return uptime;
    }
    
    public void setUptime(long uptime) {
        this.uptime = uptime;
    }
    
    public double getTasksPerSecond() {
        return tasksPerSecond;
    }
    
    public void setTasksPerSecond(double tasksPerSecond) {
        this.tasksPerSecond = tasksPerSecond;
    }
    
    public double getSuccessRate() {
        return successRate;
    }
    
    public void setSuccessRate(double successRate) {
        this.successRate = successRate;
    }
    
    public double getFailureRate() {
        return failureRate;
    }
    
    public void setFailureRate(double failureRate) {
        this.failureRate = failureRate;
    }
    
    @Override
    public String toString() {
        return "SchedulerStatistics{" +
                "totalTasks=" + totalTasks +
                ", pendingTasks=" + pendingTasks +
                ", runningTasks=" + runningTasks +
                ", successTasks=" + successTasks +
                ", failedTasks=" + failedTasks +
                ", successRate=" + String.format("%.2f", successRate) + "%" +
                ", uptime=" + (uptime / 1000) + "s" +
                '}';
    }
}
